﻿#include "MyWorld02.h"

#include "CollisionCalculate.h"

//#include "extensions/cocos-ext.h"
//#include "SimpleAudioEngine.h"

#include <ctime>
#include <ratio>       // std::ratio
#include <chrono>    // std::chrono::seconds

//#include "GeometricCalculation.h"

USING_NS_CC;
//using namespace CocosDenshion;
//USING_NS_CC_EXT;   //  看定义就知道等效于  using namespace cocos2d::extension

#define USE_THREAD_CAL  1  // 1 表示用线程计算碰撞，0表示在 update 里计算碰撞

MyWorld02::MyWorld02()
{
	CCLOG("MyWorld02  constructor ");

	// 随机数的种子
	srand((unsigned)time(nullptr));
}

MyWorld02::~MyWorld02()
{
	_stop = true;

	if (_calculateCollisionThread.joinable())
	{
		_calculateCollisionThread.join();
	}

	CCLOG("MyWorld02  destructor ");
}

#if USE_CREATE_FUNC
#else
MyWorld02* MyWorld02::create()
{
	MyWorld02 *pRet = new(std::nothrow) MyWorld02();
	if (pRet && pRet->init())
	{
		int iCount = pRet->getReferenceCount();  // 获取当前的引用计数

		pRet->autorelease();  // 将对象交给自动释放池

		iCount = pRet->getReferenceCount();

		return pRet;
	}
	else
	{
		delete pRet;
		pRet = nullptr;
		return nullptr;
	}
}
#endif

Scene* MyWorld02::createScene() {
	/* 创建一个场景对象 */
	auto scene = CCScene::create();

	/* 创建MyWorld02对象 */
	auto layer = MyWorld02::create();

	/* 添加MyWorld02到场景中 */
	scene->addChild(layer);

	return scene;
}

bool MyWorld02::init() 
{

	Size visibleSize = Director::getInstance()->getVisibleSize();	// 获得视图的尺寸
	Point origin = Director::getInstance()->getVisibleOrigin();	// 获得视图的原点

	_drawNode = DrawNode::create();
	addChild(_drawNode);

	_drawBezier = DrawNode::create();
	addChild(_drawBezier);

	int iType = 0;

	if (0 == iType)
	{
		// 检查矩阵变换
		Test01();
		Test02();
	}
	else if (1 == iType)
	{
		// 计算碰撞的行为
		addBehavior();
	}

	this->scheduleUpdate();
	
	return true;
}

#define MOVE_TO_RIGHT_TOP  1 // 1表示朝右上角方向运行，0为向左下角方向运行

// 检查矩阵变换
void MyWorld02::Test01()
{
	auto winSize = Director::getInstance()->getWinSize();

	#if MOVE_TO_RIGHT_TOP
		const int xInitPos = 0;
		const int yInitPos = 0;
	#else
		const int xInitPos = 500;
		const int yInitPos = 400;
	#endif

	_smallFish = Sprite::create("test2.png");
	#if MOVE_TO_RIGHT_TOP
		_smallFish->setPosition(Vec2(0, 0));
	#else
		_smallFish->setPosition(Vec2(xInitPos, yInitPos));
	#endif
	addChild(_smallFish);

	//_smallBullet = Sprite::create("test1.png");
	//addChild(_smallBullet);

	Mat4 mat4Fish = _smallFish->getNodeToParentTransform();
	Rect  rectFish = _smallFish->getBoundingBox();    // 里面的 origin 是指左下角的坐标

	polyon2.init(rectFish.size.width, rectFish.size.height);
	#if MOVE_TO_RIGHT_TOP
		polyon2.setPosition(0, 0);
	#else
		polyon2.setPosition(xInitPos, yInitPos);
	#endif

	#if MOVE_TO_RIGHT_TOP
		//在这里设置动作的参数
		Vec2 moveVec = Vec2(500, 300);
	#else
		//在这里设置动作的参数
		Vec2 moveVec = Vec2(0, 0);
	#endif

	float movetime = 2.0;

	#if MOVE_TO_RIGHT_TOP
		float rotateangle = 90;   // 30.0  顺时针转
	#else
		float rotateangle = -90;   // 30.0  顺时针转
	#endif

	float rotatetime = 2.0;

	// 移动的动作
	auto moveto = MoveTo::create(movetime, moveVec);
	//auto moveto = MoveBy::create(movetime, moveVec);

	// 旋转的动作
	auto rotateto = RotateTo::create(rotatetime, rotateangle);
	//auto rotateto = RotateBy::create(rotatetime, rotateangle);
	
	int iType = 4;
	if (0 == iType)  // 移动
	{
		_smallFish->runAction(moveto);
	}
	else if (1 == iType)  // 旋转
	{
		_smallFish->runAction(rotateto);
	}
	else if (2 == iType)  // 先移动再旋转
	{
		auto seq = Sequence::createWithTwoActions(moveto, rotateto);
		_smallFish->runAction(seq);
	}
	else if (3 == iType)   // 一边移动一边旋转
	{
		auto spa = Spawn::createWithTwoActions(moveto, rotateto);
		_smallFish->runAction(spa);
	}
	else if (4 == iType)  // 沿一条 Bezer 曲线移动的动作
	{
		/* 创建贝塞尔曲线的配置 */
		ccBezierConfig bezier;

		Vec2  ptBezier0(50, 400);
		Vec2  ptBezier1(200, 50);
		Vec2  ptBezier2(500, 600);
		Vec2  ptBezier3(800, 300);

		// 第0个点
		auto* pSprite_0 = Sprite::create("point.png");
		pSprite_0->setPosition(ptBezier0);
		this->addChild(pSprite_0, 2);

		_smallFish->setPosition(ptBezier0);
		polyon2.setPosition(ptBezier0.x, ptBezier0.y);

		// 第1个点
		bezier.controlPoint_1 = ptBezier1;		//波谷偏向值
		Sprite* pSprite_1 = Sprite::create("point.png");
		pSprite_1->setPosition(ptBezier1);
		this->addChild(pSprite_1, 2);

		// 第2个点
		bezier.controlPoint_2 = ptBezier2;	//波峰偏向值
		Sprite* pSprite_2 = Sprite::create("point.png");
		pSprite_2->setPosition(ptBezier2);
		this->addChild(pSprite_2, 2);


		// 第3个点
		bezier.endPosition = ptBezier3;		    //动作终点
		Sprite* pSprite_3 = Sprite::create("point.png");
		pSprite_3->setPosition(ptBezier3);
		this->addChild(pSprite_3, 2);

		if (1)   // 画 Bezier 曲线
		{
			_drawBezier->drawCubicBezier(ptBezier0, ptBezier1, ptBezier2, ptBezier3, 300, Color4F::YELLOW);
		}

		/* 创建CCBezierTo动作对象 */
		BezierTo*  bezierTo = BezierTo::create(4.0f, bezier);
		BezierBy*  bezierBy = BezierBy::create(4.0f, bezier);

		#if 1
			_smallFish->runAction(bezierTo);
		#else
			_smallFish->runAction(bezierBy);
		#endif
	}

	// 起动定时器，获得运动结果的矩阵
	this->schedule(schedule_selector(MyWorld02::getActionResultMat4), 3.0f);
}



// 获得运动结果的矩阵
void MyWorld02::getActionResultMat4(float dt)
{
	this->unschedule(schedule_selector(MyWorld02::getActionResultMat4));
}

// 计算碰撞的行为
void MyWorld02::addBehavior()
{
	auto winSize = Director::getInstance()->getWinSize();

	/* 每隔1秒执行一次 */
	this->schedule(schedule_selector(MyWorld02::countTime), 2.0f);
}

void MyWorld02::countTime(float dt)
{
	this->unschedule(schedule_selector(MyWorld02::countTime));
	_calculateCollisionThread = std::thread(&MyWorld02::calculateCollision, this);
}

void MyWorld02::calculateCollision()
{
	using namespace std;
	using namespace std::chrono;

	const int iSleepElapse = 1000;	// ms

	const int iShrink_pool_max_loop = 30;	// 多长时间收缩 CMemBlockPool2
	static int iShrink_pool_count = 0;				// CMemBlockPool2 计数器

#if USE_THREAD_CAL

	/*
	在线程里判断碰撞，几乎不影响主线程的帧率，但碰撞计算是非常耗时的，详情如下：
	1、FISH_MAX_NUM=50 ，BULLET_MAX_NUM=100 ，iMaxZoomIn=1000 ，在 PC 的 DEBUG下 的情况下：5700ms 
	      FISH_MAX_NUM=25 ，BULLET_MAX_NUM=100 ，iMaxZoomIn=1000 ，在 PC 的 DEBUG下 的情况下：2900ms 
		  说明：将鱼分成几个批次分别由几个线程来计算碰撞，是非常可取的方案。
	1、FISH_MAX_NUM=100 ，BULLET_MAX_NUM=100 ，iMaxZoomIn=1000  的情况下：
		  在 PC 的 DEBUG下，1000 倍是 11100ms ，即 11ms 判断一批 FISH_MAX_NUM 条鱼和 BULLET_MAX_NUM 个子弹的全部碰撞；
		  在 三星NOTE3 里，  1000 倍是 30000ms ，即 30ms 判断一批 FISH_MAX_NUM 条鱼和 BULLET_MAX_NUM 个子弹的全部碰撞；	
	2、FISH_MAX_NUM=50 ，BULLET_MAX_NUM=50 ，iMaxZoomIn=1000  的情况下：
		  在 PC 的 DEBUG下，1000 倍是 2983ms ，即 3ms 判断一批 FISH_MAX_NUM 条鱼和 BULLET_MAX_NUM 个子弹的全部碰撞；
		  在 三星NOTE3 里，  1000 倍是 7619ms ，即 8ms 判断一批 FISH_MAX_NUM 条鱼和 BULLET_MAX_NUM 个子弹的全部碰撞；
	*/

	const int iMaxZoomIn = 1000; 

	while (!_stop)  // 非停止状态
	{
		high_resolution_clock::time_point   timeStart = high_resolution_clock::now();   // 获得当前时间，也可以这样定义  auto timeStart
		log("Stars...");

		// 碰撞计算
		for (int iFish = 0; iFish < FISH_MAX_NUM; iFish++)  // 鱼的数量
		{
			for (int iBullet = 0; iBullet < BULLET_MAX_NUM; iBullet++)   // 子弹的数量
			{
				for (int iZoomIn = 0; iZoomIn < iMaxZoomIn; iZoomIn++)    // 放大倍数
				{
					//_fish[iFish]->setUserData();
					//_fish[iFish]->getUserData();

					int iType = 5;

					if (0 == iType)   // 取锚点值
					{
						// FISH_MAX_NUM = 100 ，BULLET_MAX_NUM = 100 ，iMaxZoomIn = 1000  的情况下：280
						cocos2d::Vec2 vec2Fish = _fish[iFish]->getPosition();   
						cocos2d::Vec2 vec2Bullet = _bullet[iBullet]->getPosition();  
					}
					else if (1 == iType)  // 取锚点值
					{
						// FISH_MAX_NUM = 100 ，BULLET_MAX_NUM = 100 ，iMaxZoomIn = 1000  的情况下：260
						int xFish = _fish[iFish]->getPositionX();   
						int yFish = _fish[iFish]->getPositionY();
						int xBullet = _bullet[iBullet]->getPositionX();   
						int yBullet = _bullet[iBullet]->getPositionY();
					}
					else if (2 == iType) // 取多边形比， getBoundingBox 函数非常耗时
					{
						// FISH_MAX_NUM = 100 ，BULLET_MAX_NUM = 100 ，iMaxZoomIn = 1000  的情况下：11300ms
						Rect  rectFish = _fish[iFish]->getBoundingBox();
						Rect  rectBullet = _bullet[iBullet]->getBoundingBox();
					}
					else if (3 == iType) // 取两个多边形比并计算碰撞，证明：碰撞算法并不耗时，耗时的是 getBoundingBox 函数
					{
						// FISH_MAX_NUM = 100 ，BULLET_MAX_NUM = 100 ，iMaxZoomIn = 1000  的情况下：11500ms
						if (_fish[iFish]->getBoundingBox().intersectsRect(_bullet[iBullet]->getBoundingBox()))
						{
							// 发生碰撞
							int iTmp = 0;
						}
					}
					else if (4 == iType) // 鱼当作多边形，子弹当作点，计算碰撞
					{
						// ISH_MAX_NUM = 50 ，BULLET_MAX_NUM = 100 ，iMaxZoomIn = 1000 ，在 PC 的 DEBUG下 的情况下：5900ms

						Rect  rectFish = _fish[iFish]->getBoundingBox();
						//int b = rectFish.getMinY();
						//int t = rectFish.getMaxY();

						int xBullet = _bullet[iBullet]->getPositionX();
						int yBullet = _bullet[iBullet]->getPositionY();
						if (xBullet >=rectFish.getMidX()  &&
							xBullet <= rectFish.getMaxX()  &&
							xBullet >= rectFish.getMinY()  &&
							xBullet <= rectFish.getMaxY() 
							)
						{
							// 发生碰撞
							int iTmp = 0;
						}
					}
					else if (5 == iType) // 获取鱼变换矩阵 
					{
						Mat4 mat4Fish = _fish[iFish]->getNodeToParentTransform();   

						#if 1  // 对比测试用
								int xFish = _fish[iFish]->getPositionX();
								int yFish = _fish[iFish]->getPositionY();
								Rect  rectFish = _fish[iFish]->getBoundingBox();
						#endif

						int itmp = 0;
					}
				}
			}
		}

		high_resolution_clock::time_point   timeEnd = high_resolution_clock::now();   // 获得当前时间，也可以这样定义  auto timeStart
		log("End...");

		duration<double, std::ratio<1, 1000>> time_span_milliseconds = duration_cast<duration<double, std::ratio<1, 1000>>>(timeEnd - timeStart);   // 间隔，以ms为单位
		duration<double, std::ratio<1, 1000000>> time_span_microseconds = duration_cast<duration<double, std::ratio<1, 1000000>>>(timeEnd - timeStart);   // 间隔，以 微秒 为单位

		log("耗时 %8.0f  毫秒 \n", time_span_milliseconds.count());
		//log("耗时 %8.0f  微秒 \n", time_span_microseconds.count());

		std::this_thread::sleep_for(std::chrono::milliseconds(iSleepElapse));		// 毫秒级睡眠
	}
#endif
}

// 画多边形，bDrawRed 为 true 表示画左下角的红点
void MyWorld02::drawProlygon(bool bDrawRed)
{
	// 鱼的当前位置
	Vec2 curPos = _smallFish->getPosition();					

	// 鱼的当前旋转角度
	float  curRotate = _smallFish->getRotation();
	
	#if 0  // 非 Bezier 曲线的切线方向移动

		// 设置多边形锚点的坐标位置，会自动移动多边形
		bool bMove = polyon2.setPosition(curPos.x, curPos.y);

		// 设置多边形的旋转角度，会自动旋转多边形
		bool bRotation = polyon2.setAngle(curRotateto);   // 多边形旋转

	#else  // 沿 Bezier 曲线的切线方向移动

		float willRotate = 0.0f;   // 将要旋转的角度，应该是计算角度差值而非

		// 设置多边形锚点的坐标位置，会自动移动多边形。通常是在沿 Bezier 曲线的切线方向移动时用到。
		bool bMove = polyon2.setPositionEx(curPos.x, curPos.y, willRotate);
		if (willRotate > 0)
			int iTmp = 0;
		float realRotate = curRotate + willRotate;

		_smallFish->setRotation(realRotate);

		// 设置多边形的旋转角度，会自动旋转多边形
		bool bRotation = polyon2.setAngle(realRotate);   // 多边形旋转
	#endif

		


	if (bMove || bRotation)
	{
		_drawNode->clear();

		// 获得多边形数组
		vector<VERTEX4> pots = polyon2.getPots();

		#if _DEBUG
				int iSize = pots.size();   // 测试用
		#endif

		// 画多边形的边框
		for (int i = 0; i < pots.size(); i++)
		{
			Vec2  p0;
			Vec2  p1;
			if (i < pots.size() - 1)
			{
				p0.x = pots[i].x;
				p0.y = pots[i].y;

				p1.x = pots[i + 1].x;
				p1.y = pots[i + 1].y;
			}
			else
			{
				// 画最后一个点的直线
				p0.x = pots[i].x;
				p0.y = pots[i].y;

				p1.x = pots[0].x;
				p1.y = pots[0].y;
			}

			// 画直线
			_drawNode->drawLine(p0, p1, Color4F::GRAY);

		}  // for 

		// 画一个红点
		Vec2  lb;   // 左下角
		lb.x = pots[0].x;
		lb.y = pots[0].y;
		_drawNode->drawDot(lb, 4.0, Color4F::RED);

	}  // if (bDraw)
}

void MyWorld02::update(float delta)
{
	if(1)
	{
		// 画多边形
		drawProlygon();
	}
}



// 对 GnsPolygon2 的操作
void MyWorld02::Test02()
{

	int iRes = 0;
	bool bRes = false;

	if (1)
	{
		VERTEX4 pPrev, pNext;

		pPrev.x = 0;
		pPrev.y = 0;

		pNext.x = 0;
		pNext.y = 3;

		float angle = polyon2.getAngleTwoPoint(pPrev, pNext);

		int iTmp = 0;
	}

	if(1)   // 简单多边形检测，顶点逆时针排列
	{
		const int iMaxCount = 4;
		Vec2   _pt;                             // 点
		Vec2	_polygonDot[iMaxCount];		// 多边形

		#if 0  // 逆时针，是OK 的
			_polygonDot[0] = Vec2(-1.0f, -1.0f);
			_polygonDot[1] = Vec2(1.0f, -1.0f);
			_polygonDot[2] = Vec2(1.0f, 1.0f);
			_polygonDot[3] = Vec2(-1.0f, 1.0f);
		#else   // 顺时针，是OK 的
			_polygonDot[0] = Vec2(-1.0f, -1.0f);
			_polygonDot[1] = Vec2(-1.0f, 1.0f);
			_polygonDot[2] = Vec2(1.0f, 1.0f);
			_polygonDot[3] = Vec2(1.0f, -1.0f);
		#endif

		_pt = Vec2(0.5f, 0.5f);   // 在多边形内
		iRes = CollisionCalculate::insidepolygon(iMaxCount, _polygonDot, _pt);
		assert(0 == iRes);

		_pt = Vec2(1.0f, 0.5f);   // 在多边形边上
		iRes = CollisionCalculate::insidepolygon(iMaxCount, _polygonDot, _pt);
		assert(1 == iRes);

		_pt = Vec2(3.0f, 3.5f);   // 在多边形边上
		iRes = CollisionCalculate::insidepolygon(iMaxCount, _polygonDot, _pt);	
		assert(2 == iRes);
	}

	if (1)  // 点与凸多边形的碰撞检测，注意：多边形 polygon 一定要是凸多边形
	{
		const int iMaxCount = 6;
		Vec2   _pt;                             // 点
		Vec2	_polygonDot[iMaxCount];		// 多边形

		#if 0  // 逆时针凸多边形，是OK 的
				_polygonDot[0] = Vec2(-1.0f, -1.0f);
				_polygonDot[1] = Vec2(1.0f, -1.0f);
				_polygonDot[2] = Vec2(1.0f, 0.0f);
				_polygonDot[3] = Vec2(1.0f, 1.0f);
				_polygonDot[4] = Vec2(-1.0f, 1.0f);
				_polygonDot[5] = Vec2(-1.0f, 0.0f);
		#else   // 顺时针凸多边形，是OK 的
				_polygonDot[0] = Vec2(-1.0f, -1.0f);
				_polygonDot[1] = Vec2(-1.0f, -0.0f);
				_polygonDot[2] = Vec2(-1.0f, 1.0f);
				_polygonDot[3] = Vec2(1.0f, 1.0f);
				_polygonDot[4] = Vec2(1.0f, 0.0f);
				_polygonDot[5] = Vec2(1.0f, -1.0f);
		#endif

		_pt = Vec2(0.5f, 0.5f);   // 在多边形内
		bRes = CollisionCalculate::InsideConvexPolygon(iMaxCount, _polygonDot, _pt);
		assert(true == bRes);

		_pt = Vec2(1.0f, 0.5f);   // 在多边形边上
		bRes = CollisionCalculate::InsideConvexPolygon(iMaxCount, _polygonDot, _pt);
		assert(true == bRes);

		_pt = Vec2(3.0f, 3.5f);   // 在多边形边上
		bRes = CollisionCalculate::InsideConvexPolygon(iMaxCount, _polygonDot, _pt);
		assert(false == bRes);
	}

	if (0)  // 点与凹多边形的碰撞检测，证明是失败的。
	{
		const int iMaxCount = 6;
		Vec2   _pt;                             // 点
		Vec2	_polygonDot[iMaxCount];		// 多边形

		#if 1  // 逆时针凹多边形，是失败 的
			_polygonDot[0] = Vec2(-1.0f, -1.0f);
			_polygonDot[1] = Vec2(1.0f, -1.0f);
			_polygonDot[2] = Vec2(0.0f, 0.0f);
			_polygonDot[3] = Vec2(1.0f, 1.0f);
			_polygonDot[4] = Vec2(-1.0f, 1.0f);
			_polygonDot[5] = Vec2(-1.0f, 0.0f);
		#else   // 顺时针凹多边形，是失败 的
			_polygonDot[0] = Vec2(-1.0f, -1.0f);
			_polygonDot[1] = Vec2(-0.0f, -0.0f);
			_polygonDot[2] = Vec2(-1.0f, 1.0f);
			_polygonDot[3] = Vec2(1.0f, 1.0f);
			_polygonDot[4] = Vec2(1.0f, 0.0f);
			_polygonDot[5] = Vec2(1.0f, -1.0f);
		#endif

		_pt = Vec2(0.0f, 0.5f);   // 在多边形内
		bRes = CollisionCalculate::InsideConvexPolygon(iMaxCount, _polygonDot, _pt);
		assert(true == bRes);

		_pt = Vec2(0.0f, 1.0f);   // 在多边形边框上
		bRes = CollisionCalculate::InsideConvexPolygon(iMaxCount, _polygonDot, _pt);
		assert(true == bRes);

		_pt = Vec2(2.0f, 2.0f);   // 在多边形外
		bRes = CollisionCalculate::InsideConvexPolygon(iMaxCount, _polygonDot, _pt);
		assert(false == bRes);
	}

	if (1)  // 判断点在多边形内，多边形可以不是简单多边形，可以不是凸多边形     
	{
		const int iMaxCount = 6;
		Vec2   _pt;                             // 点
		Vec2	_polygonDot[iMaxCount];		// 多边形

		#if 1  // 逆时针凸多边形，是OK 的
			_polygonDot[0] = Vec2(-1.0f, -1.0f);
			_polygonDot[1] = Vec2(1.0f, -1.0f);
			_polygonDot[2] = Vec2(1.0f, 0.0f);
			_polygonDot[3] = Vec2(1.0f, 1.0f);
			_polygonDot[4] = Vec2(-1.0f, 1.0f);
			_polygonDot[5] = Vec2(-1.0f, 0.0f);
		#else   // 顺时针凸多边形，是OK 的
			_polygonDot[0] = Vec2(-1.0f, -1.0f);
			_polygonDot[1] = Vec2(-1.0f, -0.0f);
			_polygonDot[2] = Vec2(-1.0f, 1.0f);
			_polygonDot[3] = Vec2(1.0f, 1.0f);
			_polygonDot[4] = Vec2(1.0f, 0.0f);
			_polygonDot[5] = Vec2(1.0f, -1.0f);
		#endif

		_pt = Vec2(0.5f, 0.5f);   // 在多边形内
		bRes = CollisionCalculate::InsidePolygon(iMaxCount, _polygonDot, _pt);
		assert(true == bRes);

		_pt = Vec2(1.0f, 0.5f);   // 在多边形边上
		bRes = CollisionCalculate::InsidePolygon(iMaxCount, _polygonDot, _pt);
		assert(true == bRes);

		_pt = Vec2(3.0f, 3.5f);   // 在多边形边上
		bRes = CollisionCalculate::InsidePolygon(iMaxCount, _polygonDot, _pt);
		assert(false == bRes);
	}

	if (1)  // 判断点在多边形内，多边形可以不是简单多边形，可以不是凸多边形     
	{
		const int iMaxCount = 6;
		Vec2   _pt;                             // 点
		Vec2	_polygonDot[iMaxCount];		// 多边形

		#if 0  // 逆时针凹多边形，是OK的
			_polygonDot[0] = Vec2(-1.0f, -1.0f);
			_polygonDot[1] = Vec2(1.0f, -1.0f);
			_polygonDot[2] = Vec2(0.0f, 0.0f);
			_polygonDot[3] = Vec2(1.0f, 1.0f);
			_polygonDot[4] = Vec2(-1.0f, 1.0f);
			_polygonDot[5] = Vec2(-1.0f, 0.0f);
		#else   // 顺时针凹多边形，是OK 的
			_polygonDot[0] = Vec2(-1.0f, -1.0f);
			_polygonDot[1] = Vec2(-0.0f, -0.0f);
			_polygonDot[2] = Vec2(-1.0f, 1.0f);
			_polygonDot[3] = Vec2(1.0f, 1.0f);
			_polygonDot[4] = Vec2(1.0f, 0.0f);
			_polygonDot[5] = Vec2(1.0f, -1.0f);
		#endif

		_pt = Vec2(0.0f, 0.5f);   // 在多边形内
		bRes = CollisionCalculate::InsidePolygon(iMaxCount, _polygonDot, _pt);
		assert(true == bRes);

		_pt = Vec2(0.0f, 1.0f);   // 在多边形边框上
		bRes = CollisionCalculate::InsidePolygon(iMaxCount, _polygonDot, _pt);
		assert(true == bRes);

		_pt = Vec2(2.0f, 2.0f);   // 在多边形外
		bRes = CollisionCalculate::InsidePolygon(iMaxCount, _polygonDot, _pt);
		assert(false == bRes);
	}

	if (1)  // 点与圆的碰撞检测，这是OK的
	{
		Vec2 o = Vec2(3.0f, 3.0f);
		float r = 1.0f;
		Vec2 p;

		p = Vec2(3.5f, 3.5f);
		bRes = CollisionCalculate::point_in_circle(o, r, p);  // 点在圆内

		p = Vec2(4.5f, 4.5f);
		bRes = CollisionCalculate::point_in_circle(o, r, p);	// 点在圆外
	}

	// 圆与多边形的碰撞检测，多边形的点在圆内(包括边界)时
	if (1)
	{
		const int iMaxCount = 6;
		Vec2   _pt;                             // 点
		Vec2	_polygonDot[iMaxCount];		// 多边形

		#if 0  // 逆时针凹多边形，是OK的
			_polygonDot[0] = Vec2(-1.0f, -1.0f);
			_polygonDot[1] = Vec2(1.0f, -1.0f);
			_polygonDot[2] = Vec2(0.0f, 0.0f);
			_polygonDot[3] = Vec2(1.0f, 1.0f);
			_polygonDot[4] = Vec2(-1.0f, 1.0f);
			_polygonDot[5] = Vec2(-1.0f, 0.0f);
		#else   // 顺时针凹多边形，是OK 的
			_polygonDot[0] = Vec2(-1.0f, -1.0f);
			_polygonDot[1] = Vec2(-0.0f, -0.0f);
			_polygonDot[2] = Vec2(-1.0f, 1.0f);
			_polygonDot[3] = Vec2(1.0f, 1.0f);
			_polygonDot[4] = Vec2(1.0f, 0.0f);
			_polygonDot[5] = Vec2(1.0f, -1.0f);
		#endif

		Vec2 center = Vec2(1.5f, 1.5f);    // 边框相交
		float radius = 1.0f;
		bRes = CollisionCalculate::CircleInsidePolygon(iMaxCount, center, radius, _polygonDot);
		assert(true == bRes);

		center = Vec2(2.0f, 1.0f);    // 边框相交
		radius = 1.0f;
		bRes = CollisionCalculate::CircleInsidePolygon(iMaxCount, center, radius, _polygonDot);
		assert(true == bRes);

		center = Vec2(3.0f, 3.0f);   // 不相交
		radius = 1.0f;
		bRes = CollisionCalculate::CircleInsidePolygon(iMaxCount, center, radius, _polygonDot);
		assert(false == bRes);
	}

	if (1)
	{
		Vec2 s1, e1, s2, e2;
		float angle = 0.0f;

		s1 = Vec2(1.0f , 1.0f);   // 线段1的起点
		e1 = Vec2(0.0f, 0.0f);	// 线段1的终点
		s2 = Vec2(1.0f, 0.0f);	// 线段2的起点
		e2 = Vec2(0.0f, 0.0f);	// 线段2的终点
		angle = CollisionCalculate::getAngleInTwoLine(s1, e1, s2, e2);	// 返回 线段 L1 与 线段L2之间的角度，360度那种角度

		s1 = Vec2(1.0f, 0.0f);	// 线段2的起点
		e1 = Vec2(0.0f, 0.0f);	// 线段2的终点
		s2 = Vec2(1.0f, 1.0f);   // 线段1的起点
		e2 = Vec2(0.0f, 0.0f);	// 线段1的终点
		angle = CollisionCalculate::getAngleInTwoLine(s1, e1, s2, e2);	// 返回 线段 L1 与 线段L2之间的角度，360度那种角度

		int iTmp = 0;
	}

	int iTmp = 0;
}
